/**
 * @file src/unpackertool/plugins/upx/upx_stub_signatures.cpp
 * @brief UPX stub signatures definitions.
 * @copyright (c) 2017 Avast Software, licensed under the MIT license
 */

#include "unpackertool/plugins/upx/upx_stub_signatures.h"

using namespace retdec::fileformat;
using namespace retdec::loader;
using namespace retdec::utils;
using namespace retdec::unpacker;

namespace retdec {
namespace unpackertool {
namespace upx {

namespace {

// Architecture x86
// File format ELF
// LZMA
Signature x86ElfLzmaSignature =
{
	0xE8, ANY, ANY, ANY, ANY, // CALL <Routine for creating memory regions>
	0xEB, 0x0E, // JMP rel +0xE
	0x5A, // POP EDX
	0x58, // POP EAX
	0x59, // POP ECX
	0x97, // XCHG EAX, EDI
	0x60, // PUSHA
	0x8A, 0x54, 0x24, 0x20, // MOV DL, [ESP + 20h]
	0xE9, 0x18, 0x0B, 0x00, 0x00, // JMP rel +0xB18
	0x60, // PUSHA
	0x8B, 0x74, 0x24, 0x24, // MOV ESI, [ESP + 24h]
	0x8B, 0x7C, 0x24, 0x2C, // MOV EDI, [ESP + 2Ch]
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0x89, 0xE5, // MOV EBP, ESP
	0x8B, 0x55, 0x28 // MOV EDX, [EBP + 28h]
};

// NRV2B Version 1
Signature x86ElfNrv2bSignature1 =
{
	0xE8, ANY, ANY, ANY, ANY, // CALL <Routine for creating memory regions>
	0xEB, 0x0E, // JMP rel +0xE
	0x5A, // POP EDX
	0x58, // POP EAX
	0x59, // POP ECX
	0x97, // XCHG EAX, EDI
	0x60, // PUSHA
	0x8A, 0x54, 0x24, 0x20, // MOV DL, [ESP + 20h]
	0xE9, 0xEE, 0x00, 0x00, 0x00, // JMP rel +0xEE
	0x60, // PUSHA
	0x8B, 0x74, 0x24, 0x24, // MOV ESI, [ESP + 24h]
	0x8B, 0x7C, 0x24, 0x2C, // MOV EDI, [ESP + 2Ch]
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0xEB, 0x0F, // JMP rel +0xF
	0x90, 0x90, 0x90, 0x90, 0x90 // NOP (5x)
};

// NRV2B Version 2
Signature x86ElfNrv2bSignature2 =
{
	0xE8, ANY, ANY, ANY, ANY, // CALL <Routine for creating memory regions>
	0x60, // PUSHA
	0x8B, 0x74, 0x24, 0x24, // MOV ESI, [ESP + 24h]
	0x8B, 0x7C, 0x24, 0x2C, // MOV EDI, [ESP + 2Ch]
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0xEB, 0x0F, // JMP rel +0xF
	0x90, 0x90, 0x90, 0x90, 0x90, // NOP (5x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x8A, 0x07, // MOV AL, [EDI]
	0x72, 0xEB, // JB rel -21
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	0x73, 0xEF, // JNB rel -17
	0x75, 0x09 // JNZ rel +0x09
};

// NRV2D Version 1
Signature x86ElfNrv2dSignature1 =
{
	0xE8, ANY, ANY, ANY, ANY, // CALL <Routine for creating memory regions>
	0xEB, 0x0E, // JMP rel +0xE
	0x5A, // POP EDX
	0x58, // POP EAX
	0x59, // POP ECX
	0x97, // XCHG EAX, EDI
	0x60, // PUSHA
	0x8A, 0x54, 0x24, 0x20, // MOV DL, [ESP + 20h]
	0xE9, 0x02, 0x01, 0x00, 0x00, // JMP rel +0x102
	0x60, // PUSHA
	0x8B, 0x74, 0x24, 0x24, // MOV ESI, [ESP + 24h]
	0x8B, 0x7C, 0x24, 0x2C, // MOV EDI, [ESP + 2Ch]
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0xEB, 0x0F, // JMP rel +0xF
	0x90, 0x90, 0x90, 0x90, 0x90 // NOP (5x)
};

// NRV2D Version 2
Signature x86ElfNrv2dSignature2 =
{
	0xE8, ANY, ANY, ANY, ANY, // CALL <Routine for creating memory regions>
	0x60, // PUSHA
	0x8B, 0x74, 0x24, 0x24, // MOV ESI, [ESP + 24h]
	0x8B, 0x7C, 0x24, 0x2C, // MOV EDI, [ESP + 2Ch]
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0xEB, 0x0F, // JMP rel +0xF
	0x90, 0x90, 0x90, 0x90, 0x90, // NOP (5x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x8A, 0x07, // MOV AL, [EDI]
	0x72, 0xEB, // JB rel -21
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	0x73, 0x0B, // JNB rel +0x0B
	0x75, 0x19 // JNZ rel +0x19
};

// NRV2E Version 1
Signature x86ElfNrv2eSignature1 =
{
	0xE8, ANY, ANY, ANY, ANY, // CALL <Routine for creating memory regions>
	0xEB, 0x0E, // JMP rel +0xE
	0x5A, // POP EDX
	0x58, // POP EAX
	0x59, // POP ECX
	0x97, // XCHG EAX, EDI
	0x60, // PUSHA
	0x8A, 0x54, 0x24, 0x20, // MOV DL, [ESP + 20h]
	0xE9, 0x12, 0x01, 0x00, 0x00, // JMP rel +0x112
	0x60, // PUSHA
	0x8B, 0x74, 0x24, 0x24, // MOV ESI, [ESP + 24h]
	0x8B, 0x7C, 0x24, 0x2C, // MOV EDI, [ESP + 2Ch]
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0xEB, 0x0F, // JMP rel +0xF
	0x90, 0x90, 0x90, 0x90, 0x90 // NOP (5x)
};

// NRV2E Version 2
Signature x86ElfNrv2eSignature2 =
{
	0xE8, ANY, ANY, ANY, ANY, // CALL <Routine for creating memory regions>
	0x60, // PUSHA
	0x8B, 0x74, 0x24, 0x24, // MOV ESI, [ESP + 24h]
	0x8B, 0x7C, 0x24, 0x2C, // MOV EDI, [ESP + 2Ch]
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0xEB, 0x0F, // JMP rel +0xF
	0x90, 0x90, 0x90, 0x90, 0x90, // NOP (5x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x8A, 0x07, // MOV AL, [EDI]
	0x72, 0xEB, // JB rel -21
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	0x73, 0x0B, // JNB rel +0x0B
	0x75, 0x28 // JNZ rel +0x28
};

// Architecture x86
// File format PE
// LZMA Version 1
Signature x86PeLzmaSignature1 =
{
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>
	0x8D, 0xBE, ANY, ANY, ANY, ANY, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0x57, // PUSH EDI
	0x89, 0xE5, // MOV EBP, ESP
	0x8D, 0x9C, 0x24, ANY, ANY, ANY, ANY, // LEA EBX, [ESP - <Needed size of stack>]
	0x31, 0xC0, // XOR EAX, EAX
	0x50, // PUSH EAX
	0x39, 0xDC, // CMP ESP, EBX
	0x75, 0xFB, // JNZ rel -5
	0x46, 0x46, // INC ESI, INC ESI
	0x53, // PUSH EBX
	0x68, CAP, CAP, CAP, CAP, // PUSH <Size of Unpacked Data>
	0x57, // PUSH EDI
	0x83, 0xC3, 0x04, // ADD EBX, 4
	0x53, // PUSH EBX
	0x68, CAP, CAP, CAP, CAP, // PUSH <Size of Packed Data>
	0x56, // PUSH ESI
	0x83, 0xC3, 0x04, // ADD EBX, 4
	0x53, 0x50, // PUSH EBX, PUSH EAX
	0xC7, 0x03, CAP, CAP, CAP, CAP // MOV DWORD PTR [EBX], <LZMA properties>
};

// LZMA Version 2 (DLL)
Signature x86PeLzmaSignature2 =
{
	0x80, 0x7C, 0x24, 0x08, 0x01, // CMP BYTE PTR [ESP + 8], 1
	0x0F, 0x85, ANY, ANY, ANY, ANY, // JNZ <behind unpacking stub>
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>
	0x8D, 0xBE, ANY, ANY, ANY, ANY, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0x57, // PUSH EDI
	0x89, 0xE5, // MOV EBP, ESP
	0x8D, 0x9C, 0x24, ANY, ANY, ANY, ANY, // LEA EBX, [ESP - <Needed size of stack>]
	0x31, 0xC0, // XOR EAX, EAX
	0x50, // PUSH EAX
	0x39, 0xDC, // CMP ESP, EBX
	0x75, 0xFB, // JNZ rel -5
	0x46, 0x46, // INC ESI, INC ESI
	0x53, // PUSH EBX
	0x68, CAP, CAP, CAP, CAP, // PUSH <Size of Unpacked Data>
	0x57, // PUSH EDI
	0x83, 0xC3, 0x04, // ADD EBX, 4
	0x53, // PUSH EBX
	0x68, CAP, CAP, CAP, CAP, // PUSH <Size of Packed Data>
	0x56, // PUSH ESI
	0x83, 0xC3, 0x04, // ADD EBX, 4
	0x53, 0x50, // PUSH EBX, PUSH EAX
	0xC7, 0x03, CAP, CAP, CAP, CAP // MOV DWORD PTR [EBX], <LZMA properties>
};

// NRV2B Version 1
Signature x86PeNrv2bSignature1 =
{
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, ANY, ANY, ANY, ANY, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0x57, // PUSH EDI
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0xEB, 0x10, // JMP rel +0x10
	0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // NOP (6x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	ANYB(0x73, 0x04), 0xEF, // JNB/JA rel -17 (0x73 or 0x77)
	0x75, 0x09 // JNZ rel +0x09
};

// NRV2B Version 2
Signature x86PeNrv2bSignature2 =
{
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, ANY, ANY, ANY, ANY, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0x57, // PUSH EDI
	0xEB, 0x0B, // JMP rel+ 0x0B
	0x90, // NOP
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	ANYB(0x73, 0x04), 0xEF, // JNB/JA rel -17 (0x73 or 0x77)
	0x75, 0x09 // JNZ rel +0x09
};

// NRV2B Version 3 (DLL)
Signature x86PeNrv2bSignature3 =
{
	0x80, 0x7C, 0x24, 0x08, 0x01, // CMP BYTE PTR [ESP + 8], 1
	0x0F, 0x85, ANY, ANY, ANY, ANY, // JNZ <behind unpacking stub>
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, ANY, ANY, ANY, ANY, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0x57, // PUSH EDI
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0xEB, 0x0D, // JMP rel +0x0D
	0x90, 0x90, 0x90, // NOP (3x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	ANYB(0x73, 0x04), 0xEF, // JNB/JA rel -17 (0x73 or 0x77)
	0x75, 0x09 // JNZ rel +0x09
};

// NRV2B Version 4
Signature x86PeNrv2bSignature4 =
{
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x60, // PUSHA
	0x8D, 0xBE, ANY, ANY, ANY, ANY, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0x57, // PUSH EDI
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0xEB, 0x10, // JMP rel +0x10
	0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // NOP (6x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x88, 0x07, // MOV [EDI], AL
	0x46, // INC ESI
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	ANYB(0x73, 0x04), 0xEF, // JNB/JA rel -17 (0x73 or 0x77)
	0x75, 0x09 // JNZ rel +0x09
};

// NRV2D Version 1
Signature x86PeNrv2dSignature1 =
{
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, ANY, ANY, ANY, ANY, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0x57, // PUSH EDI
	0xEB, 0x0B, // JMP rel+ 0x0B
	0x90, // NOP
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	ANYB(0x73, 0x04), 0x0B, // JNB/JA rel +0x0B (0x73 or 0x77)
	0x75, 0x19 // JNZ rel +0x19
};

// NRV2D Version 2
Signature x86PeNrv2dSignature2 =
{
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, ANY, ANY, ANY, ANY, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0x57, // PUSH EDI
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0xEB, 0x10, // JMP rel +0x10
	0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // NOP (6x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	ANYB(0x73, 0x04), 0x0B, // JNB/JA rel +0x0B (0x73 or 0x77)
	0x75, 0x19 // JNZ rel +0x19
};

// NRV2D Version 3 (DLL)
Signature x86PeNrv2dSignature3 =
{
	0x80, 0x7C, 0x24, 0x08, 0x01, // CMP BYTE PTR [ESP + 8], 1
	0x0F, 0x85, ANY, ANY, ANY, ANY, // JNZ <behind unpacking stub>
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, ANY, ANY, ANY, ANY, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0x57, // PUSH EDI
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0xEB, 0x0D, // JMP rel +0x0D
	0x90, 0x90, 0x90, // NOP (3x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	ANYB(0x73, 0x04), 0x0B, // JNB/JA rel +0x0B (0x73 or 0x77)
	0x75, 0x19 // JNZ rel +0x19
};

// NRV2E Version 1
Signature x86PeNrv2eSignature1 =
{
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, ANY, ANY, ANY, ANY, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0x57, // PUSH EDI
	0xEB, 0x0B, // JMP rel+ 0x0B
	0x90, // NOP
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	ANYB(0x73, 0x04), 0x0B, // JNB/JA rel +0x0B (0x73 or 0x77)
	0x75, 0x28 // JNZ rel +0x28
};

// NRV2E Version 2
Signature x86PeNrv2eSignature2 =
{
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, ANY, ANY, ANY, ANY, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0x57, // PUSH EDI
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0xEB, 0x10, // JMP rel+ 0x10
	0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // NOP (6x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	ANYB(0x73, 0x04), 0x0B, // JNB/JA rel +0x0B (0x73 or 0x77)
	0x75, 0x28 // JNZ rel +0x28
};

// NRV2E Version 3 (DLL)
Signature x86PeNrv2eSignature3 =
{
	0x80, 0x7C, 0x24, 0x08, 0x01, // CMP BYTE PTR [ESP + 8], 1
	0x0F, 0x85, ANY, ANY, ANY, ANY, // JNZ <behind unpacking stub>
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, ANY, ANY, ANY, ANY, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0x57, // PUSH EDI
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0xEB, 0x0D, // JMP rel+ 0x0D
	0x90, 0x90, 0x90, // NOP (3x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	ANYB(0x73, 0x04), 0x0B, // JNB/JA rel +0x0B (0x73 or 0x77)
	0x75, 0x28 // JNZ rel +0x28
};

// Architecture x86
// File format Mach-O
// LZMA
Signature x86MachOLzmaSignature =
{
	0xE8, ANY, ANY, ANY, ANY, // CALL <Routine for creating memory regions>
	0x60, // PUSHA
	0x8B, 0x74, 0x24, 0x24, // MOV ESI, [ESP + 24h]
	0x8B, 0x7C, 0x24, 0x2C, // MOV EDI, [ESP + 2Ch]
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0x89, 0xE5, // MOV EBP, ESP
	0x8B, 0x55, 0x28, // MOV EDX, [EBP + 28h]
	0xAC, // LODSB
	0x4A, // DEC EDX
	0x88, 0xC1, // MOV CL, AL
	0x24, 0x07, // AND AL, 7
	0xC0, 0xE9, 0x03 // SHR CL, 3
};

// NRV2B
Signature x86MachONrv2bSignature = x86ElfNrv2bSignature2;

// NRV2D
Signature x86MachONrv2dSignature = x86ElfNrv2dSignature2;

// NRV2E
Signature x86MachONrv2eSignature = x86ElfNrv2eSignature2;

// Architecture x64
// File format ELF
// LZMA
Signature x64ElfLzmaSignature =
{
	0xE8, ANY, ANY, ANY, ANY, // CALL <Routine for mapping memory regions>
	0x55, // PUSH RBP
	0x53, // PUSH RBX
	0x51, // PUSH RCX
	0x52, // PUSH RDX
	0x48, 0x01, 0xFE, // ADD RSI, RDI
	0x56, // PUSH RSI
	0x41, 0x80, 0xF8, 0x0E, // CMP R8B, 0x0E
	0x0F, 0x85, 0x6C, 0x0A, 0x00, 0x00, // JNZ rel +0xA6C
	0x55, // PUSH RBP
	0x48, 0x89, 0xE5, // MOV RBP, RSP
	0x44, 0x8B, 0x09, // MOV R9D, [RCX]
	0x49, 0x89, 0xD0 //MOV R8, RDX
};

// NRV2B
Signature x64ElfNrv2bSignature =
{
	0xFC, // CLD
	0x41, 0x5B, // POP R11
	0x41, 0x80, 0xF8, 0x02, // CMP R8B, 2
	0x74, 0x0D, // JZ rel +0x0D
	0xE9, 0x85, 0x00, 0x00, 0x00, // JMP rel +0x85
	0x48, 0xFF, 0xC6 // INC RSI
};

// NRV2D
Signature x64ElfNrv2dSignature =
{
	0xFC, // CLD
	0x41, 0x5B, // POP R11
	0x41, 0x80, 0xF8, 0x05, // CMP R8B, 5
	0x74, 0x0D, // JZ rel +0x0D
	0xE9, 0x93, 0x00, 0x00, 0x00, // JMP rel +0x93
	0x48, 0xFF, 0xC6 // INC RSI
};

// NRV2E
Signature x64ElfNrv2eSignature =
{
	0xFC, // CLD
	0x41, 0x5B, // POP R11
	0x41, 0x80, 0xF8, 0x08, // CMP R8B, 8
	0x74, 0x0D, // JZ rel +0x0D
	0xE9, 0xAC, 0x00, 0x00, 0x00, // JMP rel +0xAC
	0x48, 0xFF, 0xC6 // INC RSI
};

// Architecture x64
// File format PE
// LZMA
Signature x64PeLzmaSignature =
{
	0x53, // PUSH RBX
	0x56, // PUSH RSI
	0x57, // PUSH RDI
	0x55, // PUSH RBP
	0x48, 0x8D, 0x35, CAP, CAP, CAP, CAP, // LEA RSI, <Relative offset from this RIP to packed data>
	0x48, 0x8D, 0xBE, ANY, ANY, ANY, ANY, // LEA RDI, <Relative offset from this RIP to UPX0>
	0x57, // PUSH RDI
	0xB8, CAP, CAP, CAP, CAP, // MOV EAX, <Size of unpacked data>
	0x50, // PUSH RAX
	0x48, 0x89, 0xE1, // MOV RCX, RSP
	0x48, 0x89, 0xFA, // MOV RDX, RDI
	0x48, 0x89, 0xF7, // MOV RDI, RSI
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Size of packed data>
	0x55, // PUSH RBP
	0x48, 0x89, 0xE5, // MOV RBP, RSP
	0x44, 0x8B, 0x09, // MOV R9D, [RCX]
	0x49, 0x89, 0xD0, // MOV R8, RDX
	0x48, 0x89, 0xF2, // MOV RDX, RSI
	0x48, 0x8D, 0x77, 0x02, // LEA RSI, [RDI + 2]
	0x56, // PUSH RSI
	0x8A, 0x07, // MOV AL, [RDI]
	0xFF, 0xCA, // DEC EDX
	0x88, 0xC1 // MOV CL, AL
};

// NRV2B
Signature x64PeNrv2bSignature =
{
	0x53, // PUSH RBX
	0x56, // PUSH RSI
	0x57, // PUSH RDI
	0x55, // PUSH RBP
	0x48, 0x8D, 0x35, CAP, CAP, CAP, CAP, // LEA RSI, <Relative offset from this RIP to packed data>
	// --------------------------------------------------------------------------------------------------------------------------
	// Here are 154 bytes we are not interested in, because we won't recognize whether it is NRV2B, NRV2D or NRV2E by using these
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	ANY, ANY, ANY, ANY,
	// --------------------------------------------------------------------------------------------------------------------------
	0x73, 0xEB, // JNB rel +0xEB
	0x83, 0xE8, 0x03, // SUB EAX, 3
	0x72, 0x17, // JB rel +0x17
	0xC1, 0xE0, 0x08, // SHL EAX, 8
	0x0F, 0xB6, 0xD2, // MOVZX EDX, DL
	0x09, 0xD0, // OR EAX, EDX
	0x48, 0xFF, 0xC6, // INC RSI
	0x83, 0xF0, 0xFF, // XOR EAX, 0xFFFFFFFF
	0x0F, 0x84, 0x3A, 0x00, 0x00, 0x00, // JZ rel +0x3A
	0x48, 0x63, 0xE8, // MOVSXD RBP, EAX
	0x8D, 0x41, 0x01 // LEA EAX, [RCX + 1]
};

// NRV2D
Signature x64PeNrv2dSignature =
{
	0x53, // PUSH RBX
	0x56, // PUSH RSI
	0x57, // PUSH RDI
	0x55, // PUSH RBP
	0x48, 0x8D, 0x35, CAP, CAP, CAP, CAP, // LEA RSI, <Relative offset from this RIP to packed data>
	// --------------------------------------------------------------------------------------------------------------------------
	// Here are 163 bytes we are not interested in, because we won't recognize whether it is NRV2B, NRV2D or NRV2E by using these
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	// --------------------------------------------------------------------------------------------------------------------------
	0x73, 0xE4, // JNB rel +0xE4
	0x83, 0xE8, 0x03, // SUB EAX, 3
	0x72, 0x1B, // JB rel +0x1B
	0xC1, 0xE0, 0x08, // SHL EAX, 8
	0x0F, 0xB6, 0xD2, // MOVZX EDX, DL
	0x09, 0xD0, // OR EAX, EDX
	0x48, 0xFF, 0xC6, // INC RSI
	0x83, 0xF0, 0xFF, // XOR EAX, 0xFFFFFFFF
	0x0F, 0x84, 0x3F, 0x00, 0x00, 0x00, // JZ rel +0x3F
	0xD1, 0xF8, // SAR EAX, 1
	0x48, 0x63, 0xE8, // MOVSXD RBP, EAX
	0xEB, 0x03, // JMP rel +0x03
	0x41, 0xFF, 0xD3, // CALL R11
	0x11, 0xC9, // ADC ECX, ECX
	0x41, 0xFF, 0xD3, // CALL R11
	0x11, 0xC9, // ADC ECX, ECX
	0x75, 0x18, // JNZ rel +0x10
	0xFF, 0xC1 // INC ECX
};

// NRV2E
Signature x64PeNrv2eSignature =
{
	0x53, // PUSH RBX
	0x56, // PUSH RSI
	0x57, // PUSH RDI
	0x55, // PUSH RBP
	0x48, 0x8D, 0x35, CAP, CAP, CAP, CAP, // LEA RSI, <Relative offset from this RIP to packed data>
	// --------------------------------------------------------------------------------------------------------------------------
	// Here are 163 bytes we are not interested in, because we won't recognize whether it is NRV2B, NRV2D or NRV2E by using these
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY, ANY,
	// --------------------------------------------------------------------------------------------------------------------------
	0x73, 0xE4, // JNB rel +0xE4
	0x83, 0xE8, 0x03, // SUB EAX, 3
	0x72, 0x1D, // JB rel +0x1D
	0xC1, 0xE0, 0x08, // SHL EAX, 8
	0x0F, 0xB6, 0xD2, // MOVZX EDX, DL
	0x09, 0xD0, // OR EAX, EDX
	0x48, 0xFF, 0xC6, // INC RSI
	0x83, 0xF0, 0xFF, // XOR EAX, 0xFFFFFFFF
	0x0F, 0x84, 0x58, 0x00, 0x00, 0x00, // JZ rel +0x58
	0xD1, 0xF8, // SAR EAX, 1
	0x48, 0x63, 0xE8, // MOVSXD RBP, EAX
	0x72, 0x38, // JB rel +0x38
	0xEB, 0x0E, // JMP rel +0x0E
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x08, // JNZ rel +0x08
	0x8B, 0x1E // MOV EBX, [RSI]
};

// Architecture x64
// File format Mach-O
// LZMA
Signature x64MachOLzmaSignature = x64ElfLzmaSignature;

// NRV2B
Signature x64MachONrv2bSignature = x64ElfNrv2bSignature;

// NRV2D
Signature x64MachONrv2dSignature = x64ElfNrv2dSignature;

// NRV2E
Signature x64MachONrv2eSignature = x64ElfNrv2eSignature;

// Architecture MIPS Little-endian
// File format ELF
// LZMA
Signature mipsLeElfLzmaSignature =
{
	ANY, ANY, 0x11, 0x04, // BAL <Routine for creating memory regions>
	0x00, 0x00, 0xF7, 0x27, // ADDIU $s7, $ra, 0
	0x00, 0x00, 0x99, 0x90, // LBU $t9, 0($a0)
	0x00, 0xFA, 0x01, 0x24, // LI, $at, 0xFFFFFA00
	0x01, 0x00, 0x98, 0x90, // LBU $t8, 1($a0)
	0x07, 0x00, 0x22, 0x33, // ANDI $v0, $t9, 7
	0xC2, 0xC8, 0x19, 0x00, // SRL $t9, 3
	0x04, 0x08, 0x21, 0x03 // SLLV $at, $t9
};

// NRV2B
Signature mipsLeElfNrv2bSignature =
{
	ANY, ANY, 0x11, 0x04, // BAL <Routine for creating memory regions>
	0x00, 0x00, 0xF7, 0x27, // ADDIU $s7, $ra, 0
	0xFC, 0xFF, 0xBD, 0x27, // ADDIU $sp, -4
	0x00, 0x00, 0xBF, 0xAF, // SW $ra, 0($sp)
	0x20, 0x28, 0xA4, 0x00, // ADD $al, $a0
	0x00, 0x00, 0xE6, 0xAC, // SW $a2, 0($a3)
	0x00, 0x80, 0x0D, 0x3C, // LUI $t5, 0x8000
	0x21, 0x48, 0xA0, 0x01, // MOVE $t1, $t5
	0x01, 0x00, 0x0B, 0x24, // LI $t3, 1
	ANY, ANY, 0x11, 0x04, // BAL rel +(4*XX)
	0x01, 0x00, 0x0F, 0x24, // LI $t7, 1
	0x05, 0x00, 0xC0, 0x11, // BEQZ $t6, +20
	0x00, 0x00, 0x8E, 0x90, // LBU $t6, 0($a0)
	0x01, 0x00, 0x84, 0x24, // ADDIU $a0, 1
	0x01, 0x00, 0xC6, 0x24, // ADDIU $a2, 1
	0xF9, 0xFF, 0x00, 0x10, // B rel -28
	0xFF, 0xFF, 0xCE, 0xA0, // SB $t6, -1($a2)
	ANY, ANY, 0x11, 0x04, // BAL rel +(4*XX)
	0x40, 0x78, 0x0F, 0x00, // SLL $t7, 1
	ANY, ANY, 0x11, 0x04, // BAL rel +(4*XX)
	0x21, 0x78, 0xEE, 0x01, // ADDU $t7, $t6
	0xFB, 0xFF, 0xC0, 0x11 // BEQZ $t6, rel -20
};

// NRV2D
Signature mipsLeElfNrv2dSignature =
{
	ANY, ANY, 0x11, 0x04, // BAL <Routine for creating memory regions>
	0x00, 0x00, 0xF7, 0x27, // ADDIU $s7, $ra, 0
	0xFC, 0xFF, 0xBD, 0x27, // ADDIU $sp, -4
	0x00, 0x00, 0xBF, 0xAF, // SW $ra, 0($sp)
	0x20, 0x28, 0xA4, 0x00, // ADD $al, $a0
	0x00, 0x00, 0xE6, 0xAC, // SW $a2, 0($a3)
	0x00, 0x80, 0x0D, 0x3C, // LUI $t5, 0x8000
	0x21, 0x48, 0xA0, 0x01, // MOVE $t1, $t5
	0x01, 0x00, 0x0B, 0x24, // LI $t3, 1
	ANY, ANY, 0x11, 0x04, // BAL rel +(4*XX)
	0x01, 0x00, 0x0F, 0x24, // LI $t7, 1
	0x05, 0x00, 0xC0, 0x11, // BEQZ $t6, +20
	0x00, 0x00, 0x8E, 0x90, // LBU $t6, 0($a0)
	0x01, 0x00, 0x84, 0x24, // ADDIU $a0, 1
	0x01, 0x00, 0xC6, 0x24, // ADDIU $a2, 1
	0xF9, 0xFF, 0x00, 0x10, // B rel -28
	0xFF, 0xFF, 0xCE, 0xA0, // SB $t6, -1($a2)
	ANY, ANY, 0x11, 0x04, // BAL rel +(4*XX)
	0x40, 0x78, 0x0F, 0x00, // SLL $t7, 1
	ANY, ANY, 0x11, 0x04, // BAL rel +(4*XX)
	0x21, 0x78, 0xEE, 0x01, // ADDU $t7, $t6
	0x05, 0x00, 0xC0, 0x15, // BNEZ $t6, rel +20
	0xFE, 0xFF, 0xEE, 0x25, // ADDIU $t6, $t7, -2
	ANY, ANY, 0x11, 0x04, // BAL rel +(4*XX)
	0x21, 0x78, 0xCF, 0x01 // ADDU $t7, $t6, $t7
};

// NRV2E
Signature mipsLeElfNrv2eSignature =
{
	ANY, ANY, 0x11, 0x04, // BAL <Routine for creating memory regions>
	0x00, 0x00, 0xF7, 0x27, // ADDIU $s7, $ra, 0
	0xFC, 0xFF, 0xBD, 0x27, // ADDIU $sp, -4
	0x00, 0x00, 0xBF, 0xAF, // SW $ra, 0($sp)
	0x20, 0x28, 0xA4, 0x00, // ADD $al, $a0
	0x00, 0x00, 0xE6, 0xAC, // SW $a2, 0($a3)
	0x00, 0x80, 0x0D, 0x3C, // LUI $t5, 0x8000
	0x21, 0x48, 0xA0, 0x01, // MOVE $t1, $t5
	0x01, 0x00, 0x0B, 0x24, // LI $t3, 1
	ANY, ANY, 0x11, 0x04, // BAL rel +(4*XX)
	0x01, 0x00, 0x0F, 0x24, // LI $t7, 1
	0x05, 0x00, 0xC0, 0x11, // BEQZ $t6, +20
	0x00, 0x00, 0x8E, 0x90, // LBU $t6, 0($a0)
	0x01, 0x00, 0x84, 0x24, // ADDIU $a0, 1
	0x01, 0x00, 0xC6, 0x24, // ADDIU $a2, 1
	0xF9, 0xFF, 0x00, 0x10, // B rel -28
	0xFF, 0xFF, 0xCE, 0xA0, // SB $t6, -1($a2)
	ANY, ANY, 0x11, 0x04, // BAL rel +(4*XX)
	0x40, 0x78, 0x0F, 0x00, // SLL $t7, 1
	ANY, ANY, 0x11, 0x04, // BAL rel +(4*XX)
	0x21, 0x78, 0xEE, 0x01, // ADDU $t7, $t6
	0x05, 0x00, 0xC0, 0x15, // BNEZ $t6, rel +20
	0xFE, 0xFF, 0xEE, 0x25, // ADDIU $t6, $t7, -2
	ANY, ANY, 0x11, 0x04, // BAL rel +(4*XX)
	0x21, 0x78, 0xEE, 0x01 // ADDU $t7, $t6
};

// Architecture MIPS Big-endian
// File format ELF
// LZMA
Signature mipsBeElfLzmaSignature =
{
	0x04, 0x11, ANY, ANY, // BAL <Routine for creating memory regions>
	0x27, 0xF7, 0x00, 0x00, // ADDIU $s7, $ra, 0
	0x90, 0x99, 0x00, 0x00, // LBU $t9, 0($a0)
	0x24, 0x01, 0xFA, 0x00, // LI, $at, 0xFFFFFA00
	0x90, 0x98, 0x00, 0x01, // LBU $t8, 1($a0)
	0x33, 0x22, 0x00, 0x07, // ANDI $v0, $t9, 7
	0x00, 0x19, 0xC8, 0xC2, // SRL $t9, 3
	0x03, 0x21, 0x08, 0x04 // SLLV $at, $t9
};

// NRV2B
Signature mipsBeElfNrv2bSignature =
{
	0x04, 0x11, ANY, ANY, // BAL <Routine for creating memory regions>
	0x27, 0xF7, 0x00, 0x00, // ADDIU $s7, $ra, 0
	0x27, 0xBD, 0xFF, 0xFC, // ADDIU $sp, -4
	0xAF, 0xBF, 0x00, 0x00, // SW $ra, 0($sp)
	0x00, 0xA4, 0x28, 0x20, // ADD $al, $a0
	0xAC, 0xE6, 0x00, 0x00, // SW $a2, 0($a3)
	0x3C, 0x0D, 0x80, 0x00, // LUI $t5, 0x8000
	0x01, 0xA0, 0x48, 0x21, // MOVE $t1, $t5
	0x24, 0x0B, 0x00, 0x01, // LI $t3, 1
	0x04, 0x11, ANY, ANY, // BAL rel +(4*XX)
	0x24, 0x0F, 0x00, 0x01, // LI $t7, 1
	0x11, 0xC0, 0x00, 0x05, // BEQZ $t6, +20
	0x90, 0x8E, 0x00, 0x00, // LBU $t6, 0($a0)
	0x24, 0x84, 0x00, 0x01, // ADDIU $a0, 1
	0x24, 0xC6, 0x00, 0x01, // ADDIU $a2, 1
	0x10, 0x00, 0xFF, 0xF9, // B rel -28
	0xA0, 0xCE, 0xFF, 0xFF, // SB $t6, -1($a2)
	0x04, 0x11, ANY, ANY, // BAL rel +(4*XX)
	0x00, 0x0F, 0x78, 0x40, // SLL $t7, 1
	0x04, 0x11, ANY, ANY, // BAL rel +(4*XX)
	0x01, 0xEE, 0x78, 0x21, // ADDU $t7, $t6
	0x11, 0xC0, 0xFF, 0xFB // BEQZ $t6, rel -20
};

// NRV2D
Signature mipsBeElfNrv2dSignature =
{
	0x04, 0x11, ANY, ANY, // BAL <Routine for creating memory regions>
	0x27, 0xF7, 0x00, 0x00, // ADDIU $s7, $ra, 0
	0x27, 0xBD, 0xFF, 0xFC, // ADDIU $sp, -4
	0xAF, 0xBF, 0x00, 0x00, // SW $ra, 0($sp)
	0x00, 0xA4, 0x28, 0x20, // ADD $al, $a0
	0xAC, 0xE6, 0x00, 0x00, // SW $a2, 0($a3)
	0x3C, 0x0D, 0x80, 0x00, // LUI $t5, 0x8000
	0x01, 0xA0, 0x48, 0x21, // MOVE $t1, $t5
	0x24, 0x0B, 0x00, 0x01, // LI $t3, 1
	0x04, 0x11, ANY, ANY, // BAL rel +(4*XX)
	0x24, 0x0F, 0x00, 0x01, // LI $t7, 1
	0x11, 0xC0, 0x00, 0x05, // BEQZ $t6, +20
	0x90, 0x8E, 0x00, 0x00, // LBU $t6, 0($a0)
	0x24, 0x84, 0x00, 0x01, // ADDIU $a0, 1
	0x24, 0xC6, 0x00, 0x01, // ADDIU $a2, 1
	0x10, 0x00, 0xFF, 0xF9, // B rel -28
	0xA0, 0xCE, 0xFF, 0xFF, // SB $t6, -1($a2)
	0x04, 0x11, ANY, ANY, // BAL rel +(4*XX)
	0x00, 0x0F, 0x78, 0x40, // SLL $t7, 1
	0x04, 0x11, ANY, ANY, // BAL rel +(4*XX)
	0x01, 0xEE, 0x78, 0x21, // ADDU $t7, $t6
	0x15, 0xC0, 0x00, 0x05, // BNEZ $t6, rel +20
	0x25, 0xEE, 0xFF, 0xFE, // ADDIU $t6, $t7, -2
	0x04, 0x11, ANY, ANY, // BAL rel +(4*XX)
	0x01, 0xCF, 0x78, 0x21 // ADDU $t7, $t6, $t7
};

// NRV2E
Signature mipsBeElfNrv2eSignature =
{
	0x04, 0x11, ANY, ANY, // BAL <Routine for creating memory regions>
	0x27, 0xF7, 0x00, 0x00, // ADDIU $s7, $ra, 0
	0x27, 0xBD, 0xFF, 0xFC, // ADDIU $sp, -4
	0xAF, 0xBF, 0x00, 0x00, // SW $ra, 0($sp)
	0x00, 0xA4, 0x28, 0x20, // ADD $al, $a0
	0xAC, 0xE6, 0x00, 0x00, // SW $a2, 0($a3)
	0x3C, 0x0D, 0x80, 0x00, // LUI $t5, 0x8000
	0x01, 0xA0, 0x48, 0x21, // MOVE $t1, $t5
	0x24, 0x0B, 0x00, 0x01, // LI $t3, 1
	0x04, 0x11, ANY, ANY, // BAL rel +(4*XX)
	0x24, 0x0F, 0x00, 0x01, // LI $t7, 1
	0x11, 0xC0, 0x00, 0x05, // BEQZ $t6, +20
	0x90, 0x8E, 0x00, 0x00, // LBU $t6, 0($a0)
	0x24, 0x84, 0x00, 0x01, // ADDIU $a0, 1
	0x24, 0xC6, 0x00, 0x01, // ADDIU $a2, 1
	0x10, 0x00, 0xFF, 0xF9, // B rel -28
	0xA0, 0xCE, 0xFF, 0xFF, // SB $t6, -1($a2)
	0x04, 0x11, ANY, ANY, // BAL rel +(4*XX)
	0x00, 0x0F, 0x78, 0x40, // SLL $t7, 1
	0x04, 0x11, ANY, ANY, // BAL rel +(4*XX)
	0x01, 0xEE, 0x78, 0x21, // ADDU $t7, $t6
	0x15, 0xC0, 0x00, 0x05, // BNEZ $t6, rel +20
	0x25, 0xEE, 0xFF, 0xFE, // ADDIU $t6, $t7, -2
	0x04, 0x11, ANY, ANY, // BAL rel +(4*XX)
	0x01, 0xEE, 0x78, 0x21 // ADDU $t7, $t6
};

// Architecture ARM
// File Format ELF
// LZMA
Signature armElfLzmaSignature =
{
	// Usually located around EP + 0x17C
	0x00, 0x00, 0x00, 0x00, // ANDEQ R0, R0, R0
	0xF0, 0x4F, 0x2D, 0xE9, // STMFD SP!, {R4-R11,LR}
	0x30, 0xD0, 0x4D, 0xE2, // SUB SP, SP, #0x30
	0x00, 0x30, 0x8D, 0xE5, // STR R3, [SP]
	0x00, 0x30, 0xD0, 0xE5, // LDRB R3, [R0]
	0x02, 0x50, 0xD0, 0xE5, // LDRB R5, [R0,#2]
	0x01, 0xE0, 0xD0, 0xE5, // LDRB LR, [R0,#1]
	0x00, 0xC0, 0x9D, 0xE5, // LDR R12, [SP]
	0x14, 0x30, 0x8D, 0xE5, // STR R3, [SP,#0x14]
	0x5C, 0x30, 0x9D, 0xE5, // LDR R3, [SP,#0x5C]
	0x00, 0x40, 0xA0, 0xE3, // MOV R4, #0
	0x00, 0x40, 0x8C, 0xE5, // STR R4, [R12]
	0x00, 0x40, 0x83, 0xE5, // STR R4, [R3]
	0x14, 0xC0, 0x9D, 0xE5, // LDR R12, [SP,#0x14]
	0x01, 0x30, 0xD0, 0xE5, // LDRB R3, [R0,#1]
	0x03, 0x30, 0x8C, 0xE0 // ADD R12, R3
};

// NRV2B
Signature armElfNrv2bSignature =
{
	// Usually located around EP + 0x114
	0x04, 0x40, 0x94, 0xE0, // ADDS R4, R4, R4
	0x0E, 0xF0, 0xA0, 0x11, // MOVNE PC, LR
	0x01, 0x40, 0xD0, 0xE4, // LDRB R4, [R0], #1
	0x04, 0x40, 0xA4, 0xE0, // ADC R4, R4, R4
	0x04, 0x4C, 0xB0, 0xE1, // MOVS R4, R4, LSL#24
	0x0E, 0xF0, 0xA0, 0xE1, // RET
	0x01, 0x10, 0xA0, 0xE3, // MOV R1, #1
	0x0E, 0xC0, 0xA0, 0xE1, // MOV R12, LR
	0xF6, 0xFF, 0xFF, 0xEB, // BL rel -10
	0x01, 0x10, 0xB1, 0xE0, // ADCS R1, R1, R1
	0xF4, 0xFF, 0xFF, 0xEB, // BL rel -12
	0xFB, 0xFF, 0xFF, 0x3A // BCC rel -5
};

// NRV2D
Signature armElfNrv2dSignature =
{
	// Usually located around EP + 0x114
	0x01, 0x40, 0xD0, 0xE4, // LDRB R4, [R0], #1
	0x04, 0x40, 0xA4, 0xE0, // ADC R4, R4, R4
	0x04, 0x4C, 0xB0, 0xE1, // MOVS R4, R4, LSL#24
	0x0E, 0xF0, 0xA0, 0xE1, // RET
	0x01, 0x30, 0xD0, 0xE4, // LDRB R3, [R0], #1
	0x01, 0x30, 0xC2, 0xE4, // STRB R3, [R2], #1
	0x04, 0x40, 0x94, 0xE0, // ADDS R4, R4, R4
	0xF7, 0xFF, 0xFF, 0x0B, // BLEQ rel -9
	0xFA, 0xFF, 0xFF, 0x2A, // BCS rel -6
	0x01, 0x10, 0xA0, 0xE3, // MOV R1, #1
	0x03, 0x00, 0x00, 0xEA, // B rel +3
	0x01, 0x10, 0x41, 0xE2, // SUB R1, R1, #1
	0x04, 0x40, 0x94, 0xE0, // ADDS R4, R4, R4
	0xF1, 0xFF, 0xFF, 0x0B, // BLEQ rel -15
	0x01, 0x10, 0xB1, 0xE0 // ADCS R1, R1, R1
};

// NRV2E
Signature armElfNrv2eSignature =
{
	// Usually located around EP + 0x114
	0x01, 0x40, 0xD0, 0xE4, // LDRB R4, [R0], #1
	0x04, 0x40, 0xA4, 0xE0, // ADC R4, R4, R4
	0x04, 0x4C, 0xB0, 0xE1, // MOVS R4, R4, LSL#24
	0x0E, 0xF0, 0xA0, 0xE1, // RET
	0x01, 0x30, 0xD0, 0xE4, // LDRB R3, [R0], #1
	0x01, 0x30, 0xC2, 0xE4, // STRB R3, [R2], #1
	0x04, 0x40, 0x94, 0xE0, // ADDS R4, R4, R4
	0xF7, 0xFF, 0xFF, 0x0B, // BLEQ rel -9
	0xFA, 0xFF, 0xFF, 0x2A, // BCS rel -6
	0x01, 0x10, 0xA0, 0xE3, // MOV R1, #1
	0x03, 0x00, 0x00, 0xEA, // B rel +3
	0x01, 0x10, 0x41, 0xE2, // SUB R1, R1, #1
	0x04, 0x40, 0x94, 0xE0, // ADDS R4, R4, R4
	0xF1, 0xFF, 0xFF, 0x0B, // BLEQ rel -15
	0x01, 0x10, 0xA1, 0xE0 // ADC R1, R1, R1
};

// File Format ARM
// LZMA
Signature armMachOLzmaSignature =
{
	0x04, 0xD0, 0x4D, 0xE2, // SUB SP, SP, #4
	0xFF, 0xDF, 0x2D, 0xE9, // STMFD SP!, {R0-R12,LR,PC}
	0xB9, 0x02, 0x00, 0xEB, // BL rel +AE8
	0x00, 0xC0, 0xDD, 0xE5, // LBRB R12, [SP]
	0x0E, 0x00, 0x5C, 0xE3, // CMP R12, #0xE
	0x79, 0x02, 0x00, 0x1A, // BNE
	0x0C, 0x48, 0x2D, 0xE9, // STMFD SP!, {R2,R3,R11,LR}
	0x00, 0xB0, 0xD0, 0xE5, // LDRB R11, [R0]
	0x06, 0xCC, 0xA0, 0xE3, // MOV R12, #0x600
	0xAB, 0xB1, 0xA0, 0xE1, // MOV R11, R11, LSR#3
	0x1C, 0xCB, 0xA0, 0xE1, // MOV R12, R12, LSL R11
	0x0D, 0xB0, 0xA0, 0xE1 // MOV R11, SP
};

// NRV2B
Signature armMachONrv2bSignature =
{
	0x04, 0xD0, 0x4D, 0xE2, // SUB SP, SP, #4
	0xFF, 0xDF, 0x2D, 0xE9, // STMFD SP!, {R0-R12,LR,PC}
	0x79, 0x00, 0x00, 0xEB, // BL
	0x00, 0x10, 0x81, 0xE0, // ADD R1, R1, R0
	0x3E, 0x40, 0x2D, 0xE9, // STMFD SP!, {R1-R5,LR}
	0x00, 0x50, 0xE0, 0xE3, // MOV R5, #0xFFFFFFFF
	0x02, 0x41, 0xA0, 0xE3, // MOV R4, #0x80000000
	0x1F, 0x00, 0x00, 0xEA // B
};

// NRV2D
Signature armMachONrv2dSignature =
{
	0x04, 0xD0, 0x4D, 0xE2, // SUB SP, SP, #4
	0xFF, 0xDF, 0x2D, 0xE9, // STMFD SP!, {R0-R12,LR,PC}
	0x88, 0x00, 0x00, 0xEB, // BL
	0xFC, 0x40, 0x2D, 0xE9, // STMFD SP!, {R2-R7,LR}
	0x00, 0x70, 0x81, 0xE0, // ADD R7, R1, R0
	0x00, 0x50, 0xE0, 0xE3, // MOV R5, #0xFFFFFFFF
	0x02, 0x41, 0xA0, 0xE3, // MOV R4, #0x80000000
	0x16, 0x00, 0x00, 0xEA // B
};

// NRV2E
Signature armMachONrv2eSignature =
{
	0x04, 0xD0, 0x4D, 0xE2, // SUB SP, SP, #4
	0xFF, 0xDF, 0x2D, 0xE9, // STMFD SP!, {R0-R12,LR,PC}
	0x8D, 0x00, 0x00, 0xEB, // BL
	0xFC, 0x40, 0x2D, 0xE9, // STMFD SP!, {R2-R7,LR}
	0x00, 0x70, 0x81, 0xE0, // ADD R7, R1, R0
	0x00, 0x50, 0xE0, 0xE3, // MOV R5, #0xFFFFFFFF
	0x02, 0x41, 0xA0, 0xE3, // MOV R4, #0x80000000
	0x16, 0x00, 0x00, 0xEA // B
};

// Architecture PowerPC
// File Format ELF
// LZMA
Signature ppcElfLzmaSignature =
{
	ANYB(0x48, 0x03), ANY, ANY, ANYB(0x01, 0xFC), // BL <Routine for creating memory regions>
	0x28, 0x07, 0x00, 0x0E, // CMPLWI %R7, 0xE
	0x40, 0x82, ANY, ANYB(0x00, 0xFC), // BNE rel +XX
	0x7C, 0x08, 0x02, 0xA6, // MFLR %R0
	0x7C, 0xC9, 0x33, 0x78, // MR %R9, %R6
	0x81, 0x06, 0x00, 0x00, // LWZ %R8, 0(%R6)
	0x7C, 0xA7, 0x2B, 0x78, // MR %R7, %R5
	0x38, 0xA4, 0xFF, 0xFE, // ADDI %R5, %R4, -2
	0x38, 0x83, 0x00, 0x02, // ADDI %R4, %R3, 2
	0x90, 0x01, 0x00, 0x08, // STW %R0, 8(%SP)
	0x88, 0x03, 0x00, 0x00, // LBZ %R0, 0(%R3)
	0x54, 0x0B, 0xE8, 0xFE, // SRWI %R11, %R0, 3
	0x54, 0x02, 0x07, 0x7E // CLRLWI %RTOC, %R0, 29
};

// NRV2B
Signature ppcElfNrv2bSignature =
{
	ANYB(0x48, 0x03), ANY, ANY, ANYB(0x01, 0xFC), // BL <Routine for creating memory regions>
	0x7C, 0x00, 0x29, 0xEC, // DCBTST %R0, %R5
	0x7D, 0xA8, 0x02, 0xA6, // MFLR %R13
	0x28, 0x07, 0x00, 0x02, // CMPLWI %R7, 2
	0x40, 0x82, ANY, ANYB(0x00, 0xFC), // BNE rel +XX
	0x90, 0xA6, 0x00, 0x00, // STW %R5, 0(%R6)
	0x7C, 0x84, 0x1A, 0x14, // ADD %R4, %R4, %R3
	0x3C, 0x00, 0x80, 0x00, // LIS %R0, -0x8000
	0x3D, 0x20, 0x80, 0x00, // LIS %R9, -0x8000
	0x38, 0x63, 0xFF, 0xFF, // ADDI %R3, %R3, -1
	0x38, 0xA5, 0xFF, 0xFF, // ADDI %R5, %R5, -1
	0x39, 0x40, 0xFF, 0xFF, // LI %R10, -1
	ANYB(0x48, 0x03), ANY, ANY, ANYB(0x00, 0xFC) // B rel +XX
};

// NRV2D
Signature ppcElfNrv2dSignature =
{
	ANYB(0x48, 0x03), ANY, ANY, ANYB(0x01, 0xFC), // BL <Routine for creating memory regions>
	0x7C, 0x00, 0x29, 0xEC, // DCBTST %R0, %R5
	0x7D, 0xA8, 0x02, 0xA6, // MFLR %R13
	0x28, 0x07, 0x00, 0x05, // CMPLWI %R7, 5
	0x40, 0x82, ANY, ANYB(0x00, 0xFC), // BNE rel +XX
	0x90, 0xA6, 0x00, 0x00, // STW %R5, 0(%R6)
	0x7C, 0x84, 0x1A, 0x14, // ADD %R4, %R4, %R3
	0x3C, 0x00, 0x80, 0x00, // LIS %R0, -0x8000
	0x3D, 0x20, 0x80, 0x00, // LIS %R9, -0x8000
	0x38, 0x63, 0xFF, 0xFF, // ADDI %R3, %R3, -1
	0x38, 0xA5, 0xFF, 0xFF, // ADDI %R5, %R5, -1
	0x39, 0x40, 0xFF, 0xFF, // LI %R10, -1
	ANYB(0x48, 0x03), ANY, ANY, ANYB(0x00, 0xFC) // B rel +XX
};

// NRV2E
Signature ppcElfNrv2eSignature =
{
	ANYB(0x48, 0x03), ANY, ANY, ANYB(0x01, 0xFC), // BL <Routine for creating memory regions>
	0x7C, 0x00, 0x29, 0xEC, // DCBTST %R0, %R5
	0x7D, 0xA8, 0x02, 0xA6, // MFLR %R13
	0x28, 0x07, 0x00, 0x08, // CMPLWI %R7, 8
	0x40, 0x82, ANY, ANYB(0x00, 0xFC), // BNE rel +XX
	0x90, 0xA6, 0x00, 0x00, // STW %R5, 0(%R6)
	0x7C, 0x84, 0x1A, 0x14, // ADD %R4, %R4, %R3
	0x3C, 0x00, 0x80, 0x00, // LIS %R0, -0x8000
	0x3D, 0x20, 0x80, 0x00, // LIS %R9, -0x8000
	0x38, 0x63, 0xFF, 0xFF, // ADDI %R3, %R3, -1
	0x38, 0xA5, 0xFF, 0xFF, // ADDI %R5, %R5, -1
	0x39, 0x40, 0xFF, 0xFF, // LI %R10, -1
	ANYB(0x48, 0x03), ANY, ANY, ANYB(0x00, 0xFC) // B rel +XX
};

// Modified UPX stubs
// psyb0t - MIPS Little-endian ELF
Signature psyb0t_mipsLeElfNrv2bSignature =
{
	0xE0, 0x00, 0x11, 0x04, // BAL <Routine for creating memory regions>
	0x00, 0x00, 0xF7, 0x27, // ADDIU $s7, $ra, 0
	0x20, 0x28, 0xA4, 0x00, // ADD $a1, $a0
	0x00, 0x00, 0xE6, 0xAC, // SW $a2, 0($a3)
	0x00, 0x80, 0x0D, 0x3C, // LUI $t5, 0x8000
	0x21, 0x48, 0xA0, 0x01, // MOVE $t1, $t5
	0x01, 0x00, 0x0B, 0x24, // LI $t3, 1
	0xC2, 0x77, 0x09, 0x00 // SRL $t6, $t1, 31
};

// lshttpd - x86 ELF
Signature lshttpd_x86ElfLzmaSignature =
{
	0xE8, 0x8E, 0x0C, 0x00, 0x00, // CALL <Routine for creating memory regions>
	0x60, // PUSHA
	0x8B, 0x74, 0x24, 0x24, // MOV ESI, [ESP + 24h]
	0x8B, 0x7C, 0x24, 0x2C, // MOV EDI, [ESP + 2Ch]
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0x89, 0xE5, // MOV EBP, ESP
	0x8B, 0x55, 0x28, // MOV EDX, [EBP + 28h]
	0xAC, // LODSB
	0x4A, // DEC EDX
	0x88, 0xC1, // MOV CL, AL
	0x24, 0x07, // ADN AL, 7
	0xC0, 0xE9, 0x03, // SHR CL, 3
	0xBB, 0x00, 0xFD, 0xFF, 0xFF, // MOV EBX, 0FFFFFD00h
	0xD3, 0xE3, // SHL EBX, CL
	0x8D, 0xA4, 0x5C, 0x90, 0xF1, 0xFF, 0xFF, // LEA ESP, [ESP + EBX*2 - 0E70h]
	0x83, 0xE4, 0xE0 // AND ESP, 0FFFFFFE0h
};

// x86 PE NRV2B - Rewrites DWORD in packed data
Signature rewriteDword_x86PeNrv2bSignature1 =
{
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, CAP, CAP, CAP, CAP, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0xC7, 0x87, CAP, CAP, CAP, CAP, CAP, CAP, CAP, CAP, // MOV DWORD PTR [EDI + <Dword offset to rewrite>], <Dword to rewrite>
	0x57, // PUSH EDI
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0xEB, 0x0E, // JMP rel +0x0E
	0x90, 0x90, 0x90, 0x90, // NOP (4x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	0x73, 0xEF, // JNB rel -17
	0x75, 0x09 // JNZ rel +0x09
};

// x86 PE DLL NRV2B - Rewrites DWORD in packed data
Signature rewriteDword_x86PeNrv2bSignature2 =
{
	0x80, 0x7C, 0x24, 0x08, 0x01, // CMP BYTE PTR [ESP + 8], 1
	0x0F, 0x85, ANY, ANY, ANY, ANY, // JNZ <behind unpacking stub>
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, CAP, CAP, CAP, CAP, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0xC7, 0x87, CAP, CAP, CAP, CAP, CAP, CAP, CAP, CAP, // MOV DWORD PTR [EDI + <Dword offset to rewrite>], <Dword to rewrite>
	0x57, // PUSH EDI
	0xEB, 0x0E, // JMP rel +0x0E
	0x90, 0x90, 0x90, 0x90, // NOP (4x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	0x73, 0xEF, // JNB rel -17
	0x75, 0x09 // JNZ rel +0x09
};

// x86 PE NRV2B - Rewrites DWORD in packed data
Signature rewriteDword_x86PeNrv2bSignature3 =
{
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, CAP, CAP, CAP, CAP, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0xC7, 0x87, CAP, CAP, CAP, CAP, CAP, CAP, CAP, CAP, // MOV DWORD PTR [EDI + <Dword offset to rewrite>], <Dword to rewrite>
	0x57, // PUSH EDI
	0xEB, 0x11, // JMP rel +0x11
	0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // NOP (4x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	0x73, 0xEF, // JNB rel -17
	0x75, 0x09 // JNZ rel +0x09
};

// x86 PE NRV2D - Rewrites DWORD in packed data
Signature rewriteDword_x86PeNrv2dSignature1 =
{
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, CAP, CAP, CAP, CAP, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0xC7, 0x87, CAP, CAP, CAP, CAP, CAP, CAP, CAP, CAP, // MOV DWORD PTR [EDI + <Dword offset to rewrite>], <Dword to rewrite>
	0x57, // PUSH EDI
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0xEB, 0x0E, // JMP rel +0x0E
	0x90, 0x90, 0x90, 0x90, // NOP (4x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	0x73, 0x0B, // JNB rel +0x0B
	0x75, 0x19 // JNZ rel +0x19
};

// x86 PE DLL NRV2D - Rewrites DWORD in packed data
Signature rewriteDword_x86PeNrv2dSignature2 =
{
	0x80, 0x7C, 0x24, 0x08, 0x01, // CMP BYTE PTR [ESP + 8], 1
	0x0F, 0x85, ANY, ANY, ANY, ANY, // JNZ <behind unpacking stub>
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, CAP, CAP, CAP, CAP, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0xC7, 0x87, CAP, CAP, CAP, CAP, CAP, CAP, CAP, CAP, // MOV DWORD PTR [EDI + <Dword offset to rewrite>], <Dword to rewrite>
	0x57, // PUSH EDI
	0xEB, 0x0E, // JMP rel +0x0E
	0x90, 0x90, 0x90, 0x90, // NOP (4x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	0x73, 0x0B, // JNB rel +0x0B
	0x75, 0x19 // JNZ rel +0x19
};

// x86 PE NRV2E - Rewrites DWORD in packed data
Signature rewriteDword_x86PeNrv2eSignature1 =
{
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, CAP, CAP, CAP, CAP, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0xC7, 0x87, CAP, CAP, CAP, CAP, CAP, CAP, CAP, CAP, // MOV DWORD PTR [EDI + <Dword offset to rewrite>], <Dword to rewrite>
	0x57, // PUSH EDI
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0xEB, 0x0E, // JMP rel +0x0E
	0x90, 0x90, 0x90, 0x90, // NOP (4x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	0x73, 0x0B, // JNB rel +0x0B
	0x75, 0x28 // JNZ rel +0x28
};

// x86 PE NRV2E - Rewrites DWORD in packed data
Signature rewriteDword_x86PeNrv2eSignature2 =
{
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, CAP, CAP, CAP, CAP, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0xC7, 0x87, CAP, CAP, CAP, CAP, CAP, CAP, CAP, CAP, // MOV DWORD PTR [EDI + <Dword offset to rewrite>], <Dword to rewrite>
	0x57, // PUSH EDI
	0xEB, 0x11, // JMP rel +0x11
	0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // NOP (7x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	0x73, 0x0B, // JNB rel +0x0B
	0x75, 0x28 // JNZ rel +0x28
};

// x86 PE DLL NRV2E - Rewrites DWORD in packed data
Signature rewriteDword_x86PeNrv2eSignature3 =
{
	0x80, 0x7C, 0x24, 0x08, 0x01, // CMP BYTE PTR [ESP + 8], 1
	0x0F, 0x85, ANY, ANY, ANY, ANY, // JNZ <behind unpacking stub>
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, CAP, CAP, CAP, CAP, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0xC7, 0x87, CAP, CAP, CAP, CAP, CAP, CAP, CAP, CAP, // MOV DWORD PTR [EDI + <Dword offset to rewrite>], <Dword to rewrite>
	0x57, // PUSH EDI
	0xEB, 0x0E, // JMP rel +0x0E
	0x90, 0x90, 0x90, 0x90, // NOP (4x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	0x73, 0x0B, // JNB rel +0x0B
	0x75, 0x28 // JNZ rel +0x28
};

// x86 PE DLL NRV2E - Rewrites DWORD in packed data
Signature rewriteDword_x86PeNrv2eSignature4 =
{
	0x80, 0x7C, 0x24, 0x08, 0x01, // CMP BYTE PTR [ESP + 8], 1
	0x0F, 0x85, ANY, ANY, ANY, ANY, // JNZ <behind unpacking stub>
	0x60, // PUSHA
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, CAP, CAP, CAP, CAP, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0xC7, 0x87, CAP, CAP, CAP, CAP, CAP, CAP, CAP, CAP, // MOV DWORD PTR [EDI + <Dword offset to rewrite>], <Dword to rewrite>
	0x57, // PUSH EDI
	0xEB, 0x11, // JMP rel +0x11
	0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // NOP (7x)
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	0x73, 0x0B, // JNB rel +0x0B
	0x75, 0x28 // JNZ rel +0x28
};

// NRV2B - added PUSH instruction
// after PUSHA instruction, there is one PUSH with value 3F, but we assume it can be any other value
Signature addedPush_x86ElfNrv2bSignature =
{
	0xE8, ANY, ANY, ANY, ANY, // CALL <Routine for creating memory regions>
	0xEB, 0x0E, // JMP rel +0xE
	0x5A, // POP EDX
	0x58, // POP EAX
	0x59, // POP ECX
	0x97, // XCHG EAX, EDI
	0x60, // PUSHA
	0x8A, 0x54, 0x24, 0x20, // MOV DL, [ESP + 20h]
	0xE9, 0xF3, 0x00, 0x00, 0x00, // JMP rel +0xF3
	0x60, // PUSHA
	0x6A, ANY, // PUSH <Random Value>
	0x8B, 0x74, 0x24, 0x28, // MOV ESI, [ESP + 28h]
	0x8B, 0x7C, 0x24, 0x30, // MOV EDI, [ESP + 30h]
	0x83, 0xCD, 0xFF, // OR EBP, 0FFFFFFFFh
	0xEB, 0x11, // JMP rel +0x11
	0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 // NOP (7x)
};

// UPX$HIT
Signature upxshit_x86PeSignature =
{
	0x94, // XCHG EAX, ESP
	0xBC, CAP, CAP, CAP, CAP, // MOV ESP, <Second UPX$HIT stub address>
	0xB9, CAP, CAP, CAP, CAP, // MOV ECX, <Number of bytes to XOR>
	0x80, 0x34, 0x0C, CAP, // XOR BYTE PTR [ESP+ECX], <XOR constant>
	0xE2, 0xFA, // LOOP rel -6
	0x94, // XCHG EAX, ESP
	0xFF, 0xE0 // JMP EAX
};

// Direct Jump to UPX EP
Signature directJump_x86PeSignature =
{
	0xE9, CAP, CAP, CAP, CAP // JMP rel <UPX EP>
};

// NRV2B - PUSHA replaced with NOP
Signature pushaNop_x86PeNrv2bSignature =
{
	0x90, // NOP
	0xBE, CAP, CAP, CAP, CAP, // MOV ESI, <Address of Packed Data>]
	0x8D, 0xBE, ANY, ANY, ANY, ANY, // LEA EDI, [ESI - <offset from packed data to start of section upx0>]
	0x57, // PUSH EDI
	0xEB, 0x0B, // JMP rel+ 0x0B
	0x90, // NOP
	0x8A, 0x06, // MOV AL, [ESI]
	0x46, // INC ESI
	0x88, 0x07, // MOV [EDI], AL
	0x47, // INC EDI
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x72, 0xED, // JB rel -19
	0xB8, 0x01, 0x00, 0x00, 0x00, // MOV EAX, 1
	0x01, 0xDB, // ADD EBX, EBX
	0x75, 0x07, // JNZ rel +0x07
	0x8B, 0x1E, // MOV EBX, [ESI]
	0x83, 0xEE, 0xFC, // SUB ESI, 0FFFFFFFCh
	0x11, 0xDB, // ADC EBX, EBX
	0x11, 0xC0, // ADC EAX, EAX
	0x01, 0xDB, // ADD EBX, EBX
	ANYB(0x73, 0x04), 0xEF, // JNB/JA rel -17 (0x73 or 0x77)
	0x75, 0x09 // JNZ rel +0x09
};

} // anonymous namespace

std::vector<UpxStubData> UpxStubSignatures::allStubs =
{
	// x86 ELF
	{ Architecture::X86,    Format::ELF,    &x86ElfLzmaSignature,       UpxStubVersion::LZMA,  0x0,    0x0 },
	{ Architecture::X86,    Format::ELF,    &x86ElfNrv2bSignature1,     UpxStubVersion::NRV2B, 0x0,    0x0 },
	{ Architecture::X86,    Format::ELF,    &x86ElfNrv2bSignature2,     UpxStubVersion::NRV2B, 0x0,    0x0 },
	{ Architecture::X86,    Format::ELF,    &x86ElfNrv2dSignature1,     UpxStubVersion::NRV2D, 0x0,    0x0 },
	{ Architecture::X86,    Format::ELF,    &x86ElfNrv2dSignature2,     UpxStubVersion::NRV2D, 0x0,    0x0 },
	{ Architecture::X86,    Format::ELF,    &x86ElfNrv2eSignature1,     UpxStubVersion::NRV2E, 0x0,    0x0 },
	{ Architecture::X86,    Format::ELF,    &x86ElfNrv2eSignature2,     UpxStubVersion::NRV2E, 0x0,    0x0 },
	// x86 PE
	{ Architecture::X86,    Format::PE,     &x86PeLzmaSignature1,       UpxStubVersion::LZMA,  0xAE1,  0x0 },
	{ Architecture::X86,    Format::PE,     &x86PeLzmaSignature2,       UpxStubVersion::LZMA,  0xAE9,  0x0 },
	{ Architecture::X86,    Format::PE,     &x86PeNrv2bSignature1,      UpxStubVersion::NRV2B, 0x0D3,  0x0 },
	{ Architecture::X86,    Format::PE,     &x86PeNrv2bSignature2,      UpxStubVersion::NRV2B, 0x0CB,  0x0 },
	{ Architecture::X86,    Format::PE,     &x86PeNrv2bSignature3,      UpxStubVersion::NRV2B, 0x0DB,  0x0 },
	{ Architecture::X86,    Format::PE,     &x86PeNrv2bSignature4,      UpxStubVersion::NRV2B, 0x0D3,  0x0 },
	{ Architecture::X86,    Format::PE,     &x86PeNrv2dSignature1,      UpxStubVersion::NRV2D, 0x0DF,  0x0 },
	{ Architecture::X86,    Format::PE,     &x86PeNrv2dSignature2,      UpxStubVersion::NRV2D, 0x0E7,  0x0 },
	{ Architecture::X86,    Format::PE,     &x86PeNrv2dSignature3,      UpxStubVersion::NRV2D, 0x0EF,  0x0 },
	{ Architecture::X86,    Format::PE,     &x86PeNrv2eSignature1,      UpxStubVersion::NRV2E, 0x0EB,  0x0 },
	{ Architecture::X86,    Format::PE,     &x86PeNrv2eSignature2,      UpxStubVersion::NRV2E, 0x0F3,  0x0 },
	{ Architecture::X86,    Format::PE,     &x86PeNrv2eSignature3,      UpxStubVersion::NRV2E, 0x0FB,  0x0 },
	// x86 Mach-O
	{ Architecture::X86,    Format::MACHO,  &x86MachOLzmaSignature,     UpxStubVersion::LZMA,  0x0,    0x0 },
	{ Architecture::X86,    Format::MACHO,  &x86MachONrv2bSignature,    UpxStubVersion::NRV2B, 0x0,    0x0 },
	{ Architecture::X86,    Format::MACHO,  &x86MachONrv2dSignature,    UpxStubVersion::NRV2D, 0x0,    0x0 },
	{ Architecture::X86,    Format::MACHO,  &x86MachONrv2eSignature,    UpxStubVersion::NRV2E, 0x0,    0x0 },
	// x64 ELF
	{ Architecture::X86_64, Format::ELF,    &x64ElfLzmaSignature,       UpxStubVersion::LZMA,  0x0,    0x0 },
	{ Architecture::X86_64, Format::ELF,    &x64ElfNrv2bSignature,      UpxStubVersion::NRV2B, 0x0,    0x90 },
	{ Architecture::X86_64, Format::ELF,    &x64ElfNrv2dSignature,      UpxStubVersion::NRV2D, 0x0,    0x90 },
	{ Architecture::X86_64, Format::ELF,    &x64ElfNrv2eSignature,      UpxStubVersion::NRV2E, 0x0,    0x90 },
	// x64 PE
	{ Architecture::X86_64, Format::PE,     &x64PeLzmaSignature,        UpxStubVersion::LZMA,  0xA7B,  0x0 },
	{ Architecture::X86_64, Format::PE,     &x64PeNrv2bSignature,       UpxStubVersion::NRV2B, 0x0FB,  0x0 },
	{ Architecture::X86_64, Format::PE,     &x64PeNrv2dSignature,       UpxStubVersion::NRV2D, 0x109,  0x0 },
	{ Architecture::X86_64, Format::PE,     &x64PeNrv2eSignature,       UpxStubVersion::NRV2E, 0x122,  0x0 },
	// x64 Mach-O
	{ Architecture::X86_64, Format::MACHO,  &x64MachOLzmaSignature,     UpxStubVersion::LZMA,  0x0,    0x0 },
	{ Architecture::X86_64, Format::MACHO,  &x64MachONrv2bSignature,    UpxStubVersion::NRV2B, 0x0,    0x90 },
	{ Architecture::X86_64, Format::MACHO,  &x64MachONrv2dSignature,    UpxStubVersion::NRV2D, 0x0,    0x90 },
	{ Architecture::X86_64, Format::MACHO,  &x64MachONrv2eSignature,    UpxStubVersion::NRV2E, 0x0,    0x90 },
	// MIPS Little-endian ELF
	{ Architecture::MIPS,   Format::ELF,    &mipsLeElfLzmaSignature,    UpxStubVersion::LZMA,  0x0,    0x0 },
	{ Architecture::MIPS,   Format::ELF,    &mipsLeElfNrv2bSignature,   UpxStubVersion::NRV2B, 0x0,    0x0 },
	{ Architecture::MIPS,   Format::ELF,    &mipsLeElfNrv2dSignature,   UpxStubVersion::NRV2D, 0x0,    0x0 },
	{ Architecture::MIPS,   Format::ELF,    &mipsLeElfNrv2eSignature,   UpxStubVersion::NRV2E, 0x0,    0x0 },
	// MIPS Big-endian ELF
	{ Architecture::MIPS,   Format::ELF,    &mipsBeElfLzmaSignature,    UpxStubVersion::LZMA,  0x0,    0x0 },
	{ Architecture::MIPS,   Format::ELF,    &mipsBeElfNrv2bSignature,   UpxStubVersion::NRV2B, 0x0,    0x0 },
	{ Architecture::MIPS,   Format::ELF,    &mipsBeElfNrv2dSignature,   UpxStubVersion::NRV2D, 0x0,    0x0 },
	{ Architecture::MIPS,   Format::ELF,    &mipsBeElfNrv2eSignature,   UpxStubVersion::NRV2E, 0x0,    0x0 },
	// ARM ELF
	{ Architecture::ARM,    Format::ELF,    &armElfLzmaSignature,       UpxStubVersion::LZMA,  0x0,    0x180 },
	{ Architecture::ARM,    Format::ELF,    &armElfNrv2bSignature,      UpxStubVersion::NRV2B, 0x0,    0x120 },
	{ Architecture::ARM,    Format::ELF,    &armElfNrv2dSignature,      UpxStubVersion::NRV2D, 0x0,    0x120 },
	{ Architecture::ARM,    Format::ELF,    &armElfNrv2eSignature,      UpxStubVersion::NRV2E, 0x0,    0x120 },
	// ARM Mach-O
	{ Architecture::ARM,    Format::MACHO,  &armMachOLzmaSignature,     UpxStubVersion::LZMA,  0x0,    0x0 },
	{ Architecture::ARM,    Format::MACHO,  &armMachONrv2bSignature,    UpxStubVersion::NRV2B, 0x0,    0x0 },
	{ Architecture::ARM,    Format::MACHO,  &armMachONrv2dSignature,    UpxStubVersion::NRV2D, 0x0,    0x0 },
	{ Architecture::ARM,    Format::MACHO,  &armMachONrv2eSignature,    UpxStubVersion::NRV2E, 0x0,    0x0 },
	// PowerPC ELF
	{ Architecture::POWERPC,Format::ELF,    &ppcElfLzmaSignature,       UpxStubVersion::LZMA,  0x0,    0x0 },
	{ Architecture::POWERPC,Format::ELF,    &ppcElfNrv2bSignature,      UpxStubVersion::NRV2B, 0x0,    0x0 },
	{ Architecture::POWERPC,Format::ELF,    &ppcElfNrv2dSignature,      UpxStubVersion::NRV2D, 0x0,    0x0 },
	{ Architecture::POWERPC,Format::ELF,    &ppcElfNrv2eSignature,      UpxStubVersion::NRV2E, 0x0,    0x0 },
	// Modified UPX stubs
	// psyb0t - MIPS Little-endian ELF
	{ Architecture::MIPS,   Format::ELF,    &psyb0t_mipsLeElfNrv2bSignature,    UpxStubVersion::NRV2B, 0x0,     0x0 },
	// lshttpd - x86 ELF
	{ Architecture::X86,    Format::ELF,    &lshttpd_x86ElfLzmaSignature,       UpxStubVersion::LZMA,  0x0,     0x0 },
	// Rewrite dword - x86 PE
	{ Architecture::X86,    Format::PE,     &rewriteDword_x86PeNrv2bSignature1, UpxStubVersion::NRV2B, 0xDB,    0x0 },
	{ Architecture::X86,    Format::PE,     &rewriteDword_x86PeNrv2bSignature2, UpxStubVersion::NRV2B, 0xE3,    0x0 },
	{ Architecture::X86,    Format::PE,     &rewriteDword_x86PeNrv2bSignature3, UpxStubVersion::NRV2B, 0xDB,    0x0 },
	{ Architecture::X86,    Format::PE,     &rewriteDword_x86PeNrv2dSignature1, UpxStubVersion::NRV2D, 0xEF,    0x0 },
	{ Architecture::X86,    Format::PE,     &rewriteDword_x86PeNrv2dSignature2, UpxStubVersion::NRV2D, 0xF7,    0x0 },
	{ Architecture::X86,    Format::PE,     &rewriteDword_x86PeNrv2eSignature1, UpxStubVersion::NRV2E, 0xFB,    0x0 },
	{ Architecture::X86,    Format::PE,     &rewriteDword_x86PeNrv2eSignature2, UpxStubVersion::NRV2E, 0xFB,    0x0 },
	{ Architecture::X86,    Format::PE,     &rewriteDword_x86PeNrv2eSignature3, UpxStubVersion::NRV2E, 0x103,   0x0 },
	{ Architecture::X86,    Format::PE,     &rewriteDword_x86PeNrv2eSignature4, UpxStubVersion::NRV2E, 0x103,   0x0 },
	// UPX$HIT
	{ Architecture::X86,    Format::PE,     &upxshit_x86PeSignature,            UpxStubVersion::UPXSHIT, 0x0,   0x0 },
	// Added PUSH instruction - x86 ELF
	{ Architecture::X86,    Format::ELF,    &addedPush_x86ElfNrv2bSignature,    UpxStubVersion::NRV2B,   0x0,   0x0 },
	// Direct Jump to UPX EP
	{ Architecture::X86,    Format::PE,     &directJump_x86PeSignature,         UpxStubVersion::DIRECT_JUMP, 0x0, 0x0 },
	// NRV2B - PUSHA replaced with NOP
	{ Architecture::X86,    Format::PE,     &pushaNop_x86PeNrv2bSignature,      UpxStubVersion::NRV2B,   0xCB,  0x0 }
};

/**
 * Matches all supported signatures against the input packed file at its entry point. In the case of
 * non-matched signature with searchDistance greather than 0, the searching of the signature is performed
 * up to searchDistance from the entry point.
 *
 * @param file The input packed file.
 * @param captureData Data to capture from the signature.
 *
 * @return Pointer to valid UpxStubData structure containg all data about the unpacking stub in case of successful match, otherwise nullptr.
 */
const UpxStubData* UpxStubSignatures::matchSignatures(Image* file, DynamicBuffer& captureData)
{
	Architecture architecture = file->getFileFormat()->getTargetArchitecture();
	Format format = file->getFileFormat()->getFileFormat();

	// Find out whether file has entry point section or segment
	const retdec::loader::Segment* epSeg = file->getEpSegment();
	if (epSeg == nullptr)
		return nullptr;

	// Offset of EP in its section/segment
	unsigned long long ep;
	file->getFileFormat()->getEpAddress(ep);
	ep -= epSeg->getAddress();

	for (const UpxStubData& stubData : allStubs)
	{
		if (stubData.architecture != architecture || stubData.format != format)
			continue;

		Signature::MatchSettings settings(ep, stubData.searchDistance);
		DynamicBuffer localCaptureData(file->getFileFormat()->getEndianness());
		if (stubData.signature->match(settings, file, localCaptureData))
		{
			captureData = localCaptureData;
			return &stubData;
		}
	}

	return nullptr;
}

/**
 * Matches all supported signatures against the data buffer from its beginning. In the case of
 * non-matched signature with searchDistance greather than 0, the searching of the signature is performed
 * up to searchDistance from the its beginning.
 *
 * @param data The input data buffer.
 * @param captureData Data to capture from the signature.
 * @param architecture Architecture of the file, if any.
 * @param format File format of the file, if any.
 *
 * @return Pointer to valid UpxStubData structure containg all data about the unpacking stub in case of successful match, otherwise nullptr.
 */
const UpxStubData* UpxStubSignatures::matchSignatures(const DynamicBuffer& data, DynamicBuffer& captureData,
		retdec::fileformat::Architecture architecture /*= Architecture::UNKNOWN*/, retdec::fileformat::Format format /*= Format::UNKNOWN*/)
{
	for (const UpxStubData& stubData : allStubs)
	{
		if ((architecture != Architecture::UNKNOWN && stubData.architecture != architecture)
				|| (format != Format::UNKNOWN && stubData.format != format))
			continue;

		Signature::MatchSettings settings(0, stubData.searchDistance);
		DynamicBuffer localCaptureData(data.getEndianness());
		if (stubData.signature->match(settings, data, localCaptureData))
		{
			captureData = localCaptureData;
			return &stubData;
		}
	}

	return nullptr;
}

} // namespace upx
} // namespace unpackertool
} // namespace retdec
